Add Windows e2e tests via kind-in-WSL#1799
Conversation
5f8cdaa to
2e5646e
Compare
2e5646e to
8372b8e
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds Windows end-to-end (E2E) CI coverage by running a single-node Kubernetes control plane inside WSL (imported from kindest/node via oci-to-wsl) and executing the existing .NET E2E test suites from the Windows host through WSL2 localhost forwarding.
Changes:
- Adds a new
e2e-windows-wslGitHub Actions job that boots kind-in-WSL and runstests/E2E.Tests+tests/E2E.Aot.Testson Windows againsthttps://127.0.0.1:6443. - Introduces an
oci-to-wslprofile and a WSL-side bootstrap script to initialize Kubernetes in the imported distro. - Pins
*.shto LF line endings via.gitattributesto avoid CRLF issues when scripts are copied into WSL.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| .github/workflows/buildtest.yaml | Adds a Windows E2E job that provisions kind-in-WSL and runs the existing E2E test suites from the Windows host. |
| .github/e2e/kind-wsl.yaml | Defines the oci-to-wsl profile used to import kindest/node into a systemd-enabled WSL distro. |
| .github/e2e/bootstrap-kind.sh | Bootstraps a single-node kubeadm control plane inside the imported WSL distro. |
| .gitattributes | Forces LF line endings for .sh files to prevent WSL script execution failures. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8372b8e to
6336c12
Compare
6336c12 to
78cd893
Compare
78cd893 to
490877b
Compare
490877b to
400f208
Compare
400f208 to
430a929
Compare
5acdf7e to
ba4af61
Compare
8cf9337 to
4db8454
Compare
a9f6967 to
0ff023f
Compare
0ff023f to
297abdc
Compare
4631297 to
97d6584
Compare
97d6584 to
a66be43
Compare
a66be43 to
a6dd603
Compare
| @@ -0,0 +1,8 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
There was a problem hiding this comment.
@copilot I don't think this file is necessary
| @@ -0,0 +1,17 @@ | |||
| { | |||
| "version": "1", | |||
a6dd603 to
4de7f9b
Compare
4de7f9b to
12920ec
Compare
| void Cleanup() | ||
| { | ||
| var pods = client.CoreV1.ListNamespacedPod(namespaceParameter); | ||
| while (pods.Items.Any(p => p.Metadata.Name == podName)) | ||
| { | ||
| try | ||
| { | ||
| client.CoreV1.DeleteNamespacedPod(podName, namespaceParameter); | ||
| } | ||
| catch (HttpOperationException e) | ||
| { | ||
| if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound) | ||
| { | ||
| return; | ||
| } | ||
| } | ||
| } |
| void Cleanup() | ||
| { | ||
| var pods = client.CoreV1.ListNamespacedPod(namespaceParameter); | ||
| while (pods.Items.Any(p => p.Metadata.Name == podName)) | ||
| { | ||
| try | ||
| { | ||
| client.CoreV1.DeleteNamespacedPod(podName, namespaceParameter); | ||
| } | ||
| catch (HttpOperationException e) | ||
| { | ||
| if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound) | ||
| { | ||
| return; | ||
| } | ||
| } | ||
| } |
| var pods = client.CoreV1.ListNamespacedPod(namespaceParameter); | ||
| var pod = pods.Items.First(p => p.Metadata.Name == podName); | ||
| if (pod.Status.Phase == "Running") | ||
| { | ||
| return pod; | ||
| } | ||
|
|
||
| if (DateTime.UtcNow > deadline) | ||
| { | ||
| throw new TimeoutException($"Pod {podName} did not become Running within 2 minutes (last phase: {pod.Status.Phase})"); | ||
| } | ||
|
|
||
| await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); | ||
| } |
| # container and drives kubeadm from the host through `docker exec`; here WSL | ||
| # boots the image's systemd directly, so the equivalent bootstrap is performed | ||
| # in place. | ||
| set -euxo pipefail |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: brendandburns, tg123 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Adds a new
e2e classic (wsl)CI job that runs theKubernetesClient.Classic(.NET Framework 4.8) end-to-end tests against a real single-node Kubernetes cluster on Windows.Approach
kindest/nodeimage (which bundles containerd, the kubelet, and the K8s control-plane components) is imported into WSL2 as a systemd-enabled distro usingtg123/oci-to-wsl(SHA-pinned)..github/e2e/bootstrap-kind.shbrings up the single-node control plane inside the WSL distro: it sets up cgroupfs (no systemd cgroup delegation needed), patches out the kindest/node kubelet drop-in that assumes a Docker cgroup namespace, runskubeadm init, untaints the node, and applies the bundled kindnet CNI.certificate-authority-datais replaced withinsecure-skip-tls-verify(CI-only ephemeral cluster).tests/E2E.Classic.Tests(net48) runs in this job. The existing Linuxe2ejob continues to cover the modern (net8/9/10)E2E.TestsandE2E.Aot.Testssuites.Job requirements
runs-on: windows-2025(WSL2 only ships on Windows Server 2025;windows-latestmay still be Server 2022 with WSL1).New test project
tests/E2E.Classic.Testsmirrors the pattern used bytests/E2E.Aot.Tests: a thin csproj that links the sharedMinikubeFactAttribute.csandOnebyone.csand ships its own minimalMinikubeTests.cs(the full E2E.Tests suite depends on packages that don't support net48, such asLeaderElection,JsonPatch.Net, andKubectl).The CLA-signing commit history was preserved by squashing into a single commit authored by
Boshi LIAN <bolian@microsoft.com>.